#include "Socket.h"

Socket::Socket()
{
    _sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (_sockfd == -1)
    {
        LogMessage(FATAL, "Socket:%d:%s", errno, strerror(errno));
        exit(errno);
    }
    LogMessage(TEST, "create socket success!");
}

void Socket::SetPortReuse()
{
    int opt = 1;
    if (setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1)
    {
        LogMessage(ERROR, "SetPortReuse:%d:%s", errno, strerror(errno));
    }
    LogMessage(TEST, "set port reuse success!");
}

void Socket::Bind(uint16_t port)
{
    struct sockaddr_in local;
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_port = htons(port);
    local.sin_addr.s_addr = INADDR_ANY;

    int ret = bind(_sockfd, (sockaddr *)&local, sizeof(local));
    if (ret == -1)
    {
        LogMessage(FATAL, "Bind:%d:%s", errno, strerror(errno));
        exit(errno);
    }
    LogMessage(TEST, "bind socket success!");
}

void Socket::Listen()
{
    int ret = listen(_sockfd, s_backlog);
    if (ret == -1)
    {
        LogMessage(FATAL, "Listen:%d:%s", errno, strerror(errno));
        exit(errno);
    }
    LogMessage(TEST, "listen socket success!");
}

int Socket::Accept(string *ip, uint16_t *port)
{
    sockaddr_in client;
    socklen_t len = sizeof(client);
    int svcsock = accept(_sockfd, (sockaddr *)&client, &len);
    if (svcsock == -1)
    {
        LogMessage(ERROR, "Accept:%d:%s", errno, strerror(errno));
        return -1;
    }
    *port = ntohs(client.sin_port);
    char buffer[64];
    inet_ntop(AF_INET, &client.sin_addr, buffer, sizeof(buffer));
    *ip = buffer;
    return svcsock;
}
